<template>
  <div class="stble-diffusion-xl-wp">
  	<div class="left-box">
  		<div class="search-box" :class="{show: _d.searchShow}">
  			<div class="toggle-btn" @click="_d.searchShow = !_d.searchShow">
  				<div class="icon"></div>
  				<span class="open">展开</span>
  				<span class="close">收起</span>
  			</div>
  			<div class="form-box">
  				<div class="form-content">
  					<div class="flex" style="padding-left:6em;">
		  				<div class="row1">
			  				<div class="label">
			  					<div class="txt">选择风格</div>
			  				</div>
			  				<div class="value">
			  					<a-select class="w-full" v-model:value="_d.form.style" :options="_d.styleList" placeholder="请选择"></a-select>
			  				</div>
			  			</div>
			  			<div class="row1">
			  				<div class="label">
			  					<div class="txt">选择图片大小</div>
			  				</div>
			  				<div class="value">
			  					<a-select class="w-full" v-model:value="_d.form.size" :options="_d.sizeList" placeholder="请选择"></a-select>
			  				</div>
			  			</div>
			  			<div class="row1">
			  				<div class="label">
			  					<div class="txt">选择采样方式</div>
			  				</div>
			  				<div class="value">
			  					<a-select class="w-full" v-model:value="_d.form.sampler_index" :options="_d.samplerIndexList" placeholder="请选择"></a-select>
			  				</div>
			  			</div>
			  			<div class="row1">
			  				<div class="label">
			  					<div class="txt">生成数量</div>
			  					<div class="tip">范围1-4</div>
			  				</div>
			  				<div class="value">
			  					<a-input-number class="w-full" v-model:value="_d.form.n" :min="1" :max="4" placeholder="请输入"></a-input-number>
			  				</div>
			  			</div>
			  			<div class="row1">
			  				<div class="label">
			  					<div class="txt">迭代轮次</div>
			  					<div class="tip">范围10-50</div>
			  				</div>
			  				<div class="value">
			  					<a-input-number class="w-full" v-model:value="_d.form.steps" :min="10" :max="50" placeholder="请输入"></a-input-number>
			  				</div>
			  			</div>
		  			</div>
		  			<div class="row2">
		  				<div class="label">提示词：</div>
		  				<div class="value">
		  					<div class="nums">{{_d.form.prompt.length}}/1024</div>
		  					<a-textarea v-model:value="_d.form.prompt" 
		  						placeholder="描述您的想法，例如“一只行走在太空中的猫，黄色毛发，眼睛像车灯”"
		  						:maxLength="1024"
		  						:autosize="{minRows: 5, maxRows: 5}"></a-textarea>
		  				</div>
		  			</div>
		  			<div class="row2">
		  				<div class="label">反向提示词：</div>
		  				<div class="value">
		  					<div class="nums">{{_d.form.negative_prompt.length}}/1024</div>
		  					<a-textarea v-model:value="_d.form.negative_prompt" 
		  						placeholder="您不希望图片中出现什么？，例如：“图片中不要出现人类。”"
		  						:maxLength="1024"
		  						:autosize="{minRows: 5, maxRows: 5}"></a-textarea>
		  				</div>
		  			</div>
		  			<div class="text-center mt-10">
		  				<a-button type="primary" :loading="_d.btnLoading" @click="doCreate()">开始创作</a-button>
		  			</div>
  				</div>
	  		</div>
  		</div>

  		<div class="model-box">
				<mModelSelect ref="modelSelectRef"/>
			</div>

			<div class="list">
				<div  v-if="!_d.list.length" style="padding-top: 200px;">
					<a-empty description="暂无图片" />
				</div>

				<div v-for="(item, index) in _d.list" :key="item.batchId">
					<div class="row me">
						<div class="content">
							<div class="head">
								{{userStore.userinfo.name.length > 2 ? userStore.userinfo.name.slice(userStore.userinfo.name.length - 2) : userStore.userinfo.name}}
							</div>
							<div class="msg-box">
								<div>{{item.prompt}}</div>
							</div>
						</div>
					</div>
					<div class="row">
						<div class="content">
							<div class="head"></div>
							<div class="msg-box">
								<div class="img-list">
									<mImgShow v-for="(aItem, aIndex) in item.images" :key="aIndex" class="img" :src="aItem"  @click="showImage(aItem)"/>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
  	</div>

  	<systemBox v-model="_d.modelType"/>


  	<a-image 
      :style="{ display: 'none' }"
      :preview="{
        visible: _d.preview.visible,
        onVisibleChange: (val) => _d.preview.visible = val,
      }"
      :src="_d.preview.src"/>

  </div>
</template>

<script setup>
	import { reactive, ref, onMounted } from 'vue'
	import mImgShow from "@/components/mImgShow/index.vue";
	import systemBox from "./modules/systemBox.vue";
	import mModelSelect from "@/components/mModelSelect/index.vue";
	import {useUserStore} from '@/store/userStore';
	import {notification} from "ant-design-vue";
	import MPageLoading from "@/components/MPageLoading/index.js";
	import {ApiGet, ApiPost, ApiDownGet} from "@/api/request.js"

	const userStore = useUserStore();

	const _d = reactive({
		searchShow: false,
		btnLoading: false,

		modelurl: '', // 模型url
		form: {
			style: 'Base',
			size: '1024x1024',
			sampler_index: 'Euler a',
			n: 1,
			steps: 20,
			prompt: '',
			negative_prompt: '',
			cfg_scale: 10,
		},

		styleList: [],

		sizeList: [],

		samplerIndexList: [],

		preview: {
			visible: false,
			src: ''
		},

		list: [],
	})
	
	onMounted(() => {
		userStore.setModelType('Stable-Diffusion-XL');

		// 获取尺寸列表
		getSizeList();
		// 获取采样方式列表
		getSamplerIndexList();
		// 获取风格列表
		getStyleList();

		// 获取模型url
		getModelUrl();

		// 获取历史图片
		getHistory();
	})

	// 获取尺寸列表
	function getSizeList() {
		ApiPost('/Chat/getsize_baidu').then(res => {
			let list = [];
			for(let key in res.data) {
				list.push({
					label: key,
					value: res.data[key]
				})
			}
			_d.sizeList = list;
		})
	}

	// 获取采样方式列表
	function getSamplerIndexList() {
		ApiPost('/Chat/getsampler_baidu').then(res => {
			let list = [];
			for(let key in res.data) {
				list.push({
					label: key,
					value: res.data[key]
				})
			}
			_d.samplerIndexList = list;
		})
	}

	// 获取风格列表
	function getStyleList() {
		ApiPost('/Chat/getstyle_baidu').then(res => {
			let list = [];
			for(let key in res.data) {
				list.push({
					label: key,
					value: res.data[key]
				})
			}
			_d.styleList = list;
		})
	}

	// 获取模型url
	function getModelUrl() {
		ApiGet('/Chat/getqianfanimagemodels').then(res => {
			_d.modelurl = res.data['Stable-Diffusion-XL'];
		})
	}

	// 获取历史图片
	function getHistory() {
		MPageLoading(true, {
			text: '加载中...'
		})
		ApiPost('/Chat/getimages?id='+userStore.userinfo.userId).then(res => {
			let list = [];
			res.data.reverse().forEach(item => {
				let oItem = list.find(bItem => bItem.batchId == item.batchId);
				if(oItem) {
					oItem.images.push(item.content);
				} else {
					list.push({
						batchId: item.batchId,
						prompt: item.prompt,
						images: [item.content]
					})
				}
			})
			_d.list = list;
		}).finally(() => {
			MPageLoading(false);
		})
	}

	// 制作文生图
	function doCreate() {
		let msg = '';
		if(!_d.form.prompt) {
			msg = '提示词不能为空';
		} else if (!_d.form.n) {
			msg = '生成数量不能为空';
		} else if(!_d.form.steps) {
			msg = '迭代轮次不能为空';
		}
		if(msg) {
			notification.error({
				message: '提示',
				description: msg
			})
			return;
		}
		let params = {
			userId: userStore.userinfo.userId,
			options: {
				..._d.form,
			},
			modelurl: _d.modelurl
		}
		_d.btnLoading = true;
		_d.list.unshift({
			prompt: _d.form.prompt,
			batchId: '111',
			images: [...new Array(_d.form.n)]
		})
		_d.searchShow = false;
		ApiPost('/Chat/Startimage_baidu', params).then(res => {
			let obj = _d.list[0];
			obj.batchId = res.data.batchId;
			res.data.images.forEach((item, index) => {
				obj.images[index] = 'data:image/jpg;base64,'+item.base64;
			})
		}).finally(() => {
			_d.btnLoading = false;
		})
	}


	// 显示图片
	function showImage(image) {
		if(!image) {
			return;
		}
		_d.preview.src = image;
		_d.preview.visible = true;
	}

</script>

<style lang="less" scoped>
.stble-diffusion-xl-wp {
	height: 100vh;
	width: 100vw;
	display: flex;
	background: #F5F7F9;

	.left-box {
		flex: 1;
		width: 0;
		height: 100vh;
		position: relative;
		display: flex;
		flex-direction: column;
		&:before {
			content: '';
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			height: 56px;
			background: #F5F8F7;
			border-bottom: 1px solid #DDE0D7;
		};
		.search-box {
			margin-bottom: 46px;
			position: relative;
			background: #fff;
			&.show {
				.toggle-btn {
					.icon {
						transform: rotate(-90deg);
					}
					.open {
						display: none;
					}
					.close {
						display: inline-block;
					}
				}
				.form-box {
					height: 406px;
					border-color: #7F7F7F;
				}
			}

			.toggle-btn {
				position: absolute;
				z-index: 10;
				left: 50%;
				bottom: -46px;
				margin-left: -50px;
				background: #efefef;
				width: 100px;
				height: 36px;
				border: 1px solid #dfdfdf;
				border-radius: 6px;
				display: flex;
				justify-content: center;
				align-items: center;
				font-size: 16px;
				cursor: pointer;
				&:hover {
					color: #000;
				}
				.icon {
					margin-right: 5px;
					transform: rotate(90deg);
					&:before {
						content: '>';
						font-size: 20px;
						font-weight: 600;
						line-height: 30px;
						font-family: '宋体';
					}
				}
				.open {
					display: inline-block;
				}
				.close {
					display: none;
				}
			}
			.form-box {
				margin: 0 10px;
				height: 0;
				overflow: hidden;
				border: 1px solid transparent;
				border-radius: 10px;
				transition: height .3s;
				.form-content {
					margin: 0 auto;
					padding: 20px 10px 10px;
					width: 884px;
				}
				.row1 {
					&+.row1 {
						margin-left: 10px;
					}
					.label {
						height: 40px;
						.txt {
							line-height: 20px;
						}
						.tip {
							color: #aaa;
							font-size: 12px;
							line-height: 18px;
						}
					}
					.value {
						width: 120px;
					}
				}
				.row2 {
					margin-top: 10px;
					display: flex;
					.label {
						width: 6em;
						text-align: right;
					}
					.value {
						position: relative;
						width: 0;
						flex: 1;
						.nums {
							position: absolute;
							left: 100%;
							top: 0;
							padding-left: 10px;
							font-size: 12px;
						}
					}
				}
			}
		}

		.list {
			flex: 1;
			height: 0;
			overflow: auto;
			.row {
				&.me {
					background: #fff;
					.content {
						padding-bottom: 20px;
					}
					.head {
						background: #9951AB;
						color: #fff;
						text-align: center;
						font-size: 14px;
						line-height: 30px;
					}
				}
				&:not(.me) {
					.head {
						background: url(@/assets/image/chat.png) no-repeat center;
						background-size: 100% 100%;
					}
				}
				border-bottom: 1px solid #EDEDEE;
				.content {
					position: relative;
					margin: 0 auto;
					max-width: 960px;
					padding: 20px 20px 0 54px;

					.head {
						position: absolute;
						top: 17px;
						left: 0;
						width: 30px;
						height: 30px;
					}

					.img-list {
						&:after {
							content: '';
							display: block;
							clear: both;
						}
						.img {
							float: left;
							margin-right: 20px;
							margin-bottom: 20px;
							width: 200px;
							height: 200px;
							cursor: pointer;
						}
					}
				}
			}
		}
	}

	.model-box {
		position: absolute;
		z-index: 20;
		right: 20px;
		top: 12px;
	}

}
</style>